/*
This example reads from the default PCM device
and writes to standard output for 5 seconds of data.
*/
 
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
 
#include <alsa/asoundlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>

#define HELLO_PORT 12345
#define HELLO_GROUP "192.168.1.5"
 
int main() 
{
		long loops;
		int rc;
		int size;
		snd_pcm_t *handle;
		snd_pcm_hw_params_t *params;
		unsigned int val;
		int dir;
		snd_pcm_uframes_t frames;
		char *buffer;
     struct sockaddr_in addr;
     int fd, cnt;
     struct ip_mreq mreq;
     
     char *message="Hello, World!";

     /* create what looks like an ordinary UDP socket */
     if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) 
     {
				perror("socket");
				exit(1);
     }

     /* set up destination address */
     memset(&addr,0,sizeof(addr));
     addr.sin_family=AF_INET;
     addr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
     addr.sin_port=htons(HELLO_PORT);
     
     #if 0
     /* now just sendto() our destination! */
     while (1) 
     {
	  if (sendto(fd,message,sizeof(message),0,(struct sockaddr *) &addr,
		     sizeof(addr)) < 0) {
	       perror("sendto");
	       exit(1);
	  }
	  sleep(1);
     }
     	#endif
     
     		 
		/* Open PCM device for recording (capture). */
		rc = snd_pcm_open(&handle, "default",
				                SND_PCM_STREAM_CAPTURE, 0);
		if (rc < 0) {
				fprintf(stderr,
				        "unable to open pcm device: %s\n",
				        snd_strerror(rc));
				exit(1);
		}
		 
		/* Allocate a hardware parameters object. */
		snd_pcm_hw_params_alloca(&params);
		 
		/* Fill it in with default values. */
		snd_pcm_hw_params_any(handle, params);
		 
		/* Set the desired hardware parameters. */
		 
		/* Interleaved mode */
		snd_pcm_hw_params_set_access(handle, params,
				                  SND_PCM_ACCESS_RW_INTERLEAVED);
		 
		/* Signed 16-bit little-endian format */
		snd_pcm_hw_params_set_format(handle, params,
				                          SND_PCM_FORMAT_S16_LE);
		 
		/* Two channels (stereo) */
		snd_pcm_hw_params_set_channels(handle, params, 2);
		 
		/* 44100 bits/second sampling rate (CD quality) */
		val = 44100;
		snd_pcm_hw_params_set_rate_near(handle, params,
				                              &val, &dir);
		 
		/* Set period size to 32 frames. */
		frames = 32;
		snd_pcm_hw_params_set_period_size_near(handle,
				                          params, &frames, &dir);
		 
		/* Write the parameters to the driver */
		rc = snd_pcm_hw_params(handle, params);
		if (rc < 0) {
				fprintf(stderr,
				        "unable to set hw parameters: %s\n",
				        snd_strerror(rc));
				exit(1);
		}
		 
		/* Use a buffer large enough to hold one period */
		snd_pcm_hw_params_get_period_size(params,
				                                  &frames, &dir);
		//size = frames * 4; /* 2 bytes/sample, 2 channels */
		size=128;
		buffer = (char *) malloc(size);
		 
		/* We want to loop for 5 seconds */
		snd_pcm_hw_params_get_period_time(params,
				                                     &val, &dir);
		loops = 5000000 / val;
		 
//		while (loops > 0) 
		while(1)
		{				
					#if 1
				loops--;					
				rc = snd_pcm_readi(handle, buffer, frames);
				if (rc == -EPIPE) {
				  /* EPIPE means overrun */
				  fprintf(stderr, "overrun occurred\n");
				  snd_pcm_prepare(handle);
				} else if (rc < 0) {
				  fprintf(stderr,
				          "error from read: %s\n",
				          snd_strerror(rc));
				} else if (rc != (int)frames) {
				  fprintf(stderr, "short read, read %d frames\n", rc);
				}
				#endif
				


#if 0
			 rc = read(0, buffer, size); 
						printf("发出%d字节, size=%d\n", rc, size);
			 if (rc == 0) 
			 {   
				  fprintf(stderr, "end of file on input\n");    
				  break;   
		 	}
			else if (rc != size) 
			{     
					fprintf(stderr, "short read: read %d bytes\n", rc);
			}  
#endif							
				if (sendto(fd, buffer, size, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) 
				{
					   perror("sendto");
					   exit(1);
				}				
					  usleep(10);
				//rc = write(1, buffer, size);
				
				//if (rc != size)
				//  fprintf(stderr,
				//          "short write: wrote %d bytes\n", rc);
		}
		 
		snd_pcm_drain(handle);
		snd_pcm_close(handle);
		free(buffer);
		 
		return 0;
}
